常用Linux命令

Posted by Pallu Liu on 2020-05-01

rsync命令

rsync常用的几个Options

--remove-source-files

使用该选项后,源端已经更新成功的文件都会被删除;源端所有未传输或未传输成功的文件都不会被移除。
未传输成功的原因有多种,如exclude排除了,"quick check"未选项该文件,传输中断等等。
总之,显示在 rsync -v, 打印输出在命令行上的被传输列表中的文件都会被移除

--exclude

使用--exclude选项指定排除规则,可以排除掉在源端那些不需要传输的文件
一个--exclude只能指定一条规则,要指定多条排除规则,需要使用多个"–exclude"选项,或者将排除规则写入到文件中,然后使用--exclude-from选项读取该规则文件。

关于规则,最重要的一点是它的作用时间:
当发送端敲出rsync命令后,rsync将立即扫描命令行中给定的文件和目录(扫描过程中还会按照目录进行排序,将同一个目录的文件放在相邻的位置),这称为拷贝树(copy tree),扫描完成后将待传输的文件或目录记录到文件列表中,然后将文件列表传输给接收端(Stage 1)
而筛选规则的作用时刻是在扫描拷贝树时,所以会根据规则来匹配并决定文件是否记录到文件列表中(严格地说是会记录到文件列表中的,只不过排除的文件会被标记为hide隐藏起来),只有记录到了文件列表中的文件或目录才是真正需要传输的内容。换句话说,筛选规则的生效时间在rsync整个同步过程中是非常靠前的,它会影响很多选项的操作对象,最典型的如"–delete"

--delete

使用 --delete 选项后,接收端的rsync会先删除目标目录下已经存在,但源端目录不存在的文件。也就是"多则删之,少则补之"

如果将 --delete 选项和 --exclude 选项一起使用,那接受端存在 --exclude 设置的过滤规则里的文件,由于“看不到”源端不存在这些文件,不是把这些文件删除了吗?答案是:被排除的文件不会被删除。

在发送端将文件列表发送给接收端后,接收端的generator进程会扫描每个文件列表中的信息,然后对列表中的每个信息条目都计算数据块校验码,最后将数据库校验码发给发送端,发送端通过校验码来匹配哪些数据块是需要传输的,这样就实现了增量传输的功能——只传输改变的部分,不会传输整个文件。而delete删除的时间点是generator进程处理每个文件列表时、生成校验码之前进行的,先将目标上存在但源上不存在的多余文件删除,这样就无需为多余的文件生成校验码(Stage 2)

delete 动作是比 --exclude 规则更晚执行的,被 --exclude 规则排除的文件不会进入文件列表中,在执行了 delete 时会认为该文件不存在于源端,从而导致目标端将这些文件删除
但这是想当然的,尽管理论上确实是这样的,但是rsync为了防止众多误删除情况,提供了两种规则:保护规则(protect)和取消保护规则(risk): 默认情况下,--delete--exclude 一起使用时,虽然发送端的 --exclude 规则将文件标记为隐藏,使得接收端认为这些被排除文件在源端不存在,但rsync同时会将这些隐藏文件标记为保护文件,使得它们不受 --delete 行为的影响,这样 --delete 就删除不了这些被排除的文件。如果还是想要强行删除被 --exclude 排除的文件,可以使用--delete-excluded选项强制取消保护,这样即使被排除的文件也会被删除

利用rsync快速删除大量小文件

1
2
3
4
5
6
7
8
9
10
11
12
# 建立一个空目录
mkdir -p /del_blank
# 确立需要清空的目标目录:/del_data
# 使用rsync同步删除(注意目录后面的“/”),整体效率会快一个数量级的样子。
rsync --delete-before -a -H -v --progress --stats ./del_blank/ ./del_data/
# 选项说明:
# –delete-before 接收者在传输之前就删除那些在接收端存在,而传输端不存在的文件
# –progress 在传输时显示传输过程
# -a 归档模式,表示以递归方式传输文件,并保持所有文件属性
# -H 保持硬连接的文件
# -v 详细输出模式
# -stats 给出某些文件的传输状态
1
2
# 一般我们不需要显示进度,使用以下命令即可
rsync --delete-before -a -H ./del_blank/ ./del_data/

参考

- [1] rsync: 基本命令和用法
- [2] Linux快速复制或删除大量小文件